In [1]:
import yfinance as yf
import pandas as pd
from datetime import datetime
In [2]:
def download_all_call_options_data(symbol):
    ticker = yf.Ticker(symbol)
    expiration_dates = ticker.options

    all_call_options_data = pd.DataFrame()  # DataFrame to store all call option data

    for exp_date in expiration_dates:
        option_chain_data = ticker.option_chain(exp_date)
        calls = option_chain_data.calls

        # Add a column to indicate the expiration date for this call option DataFrame
        calls['ExpirationDate'] = exp_date

        # Concatenate this expiration date's call option DataFrame to the all_call_options_data DataFrame
        all_call_options_data = pd.concat([all_call_options_data, calls], ignore_index=True)

    return all_call_options_data

symbol = "AAPL"  # Replace this with the desired stock symbol
options_data = download_all_call_options_data(symbol)
In [3]:
options_data
Out[3]:
contractSymbol lastTradeDate strike lastPrice bid ask change percentChange volume openInterest impliedVolatility inTheMoney contractSize currency ExpirationDate
0 AAPL230811C00050000 2023-07-11 13:44:51+00:00 50.0 138.21 131.20 132.45 0.000000 0.000000 NaN 0 4.968754 True REGULAR USD 2023-08-11
1 AAPL230811C00080000 2023-07-18 19:50:00+00:00 80.0 114.55 101.60 102.80 0.000000 0.000000 1.0 1 2.898440 True REGULAR USD 2023-08-11
2 AAPL230811C00085000 2023-07-26 14:23:23+00:00 85.0 108.99 96.35 98.35 0.000000 0.000000 NaN 1 2.923831 True REGULAR USD 2023-08-11
3 AAPL230811C00095000 2023-07-19 17:26:07+00:00 95.0 99.95 86.35 88.75 0.000000 0.000000 1.0 1 2.728519 True REGULAR USD 2023-08-11
4 AAPL230811C00100000 2023-08-04 14:09:41+00:00 100.0 85.17 81.35 83.80 85.170000 NaN 3.0 0 2.556644 True REGULAR USD 2023-08-11
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
819 AAPL251219C00270000 2023-08-04 19:11:01+00:00 270.0 8.60 8.25 8.65 -2.370000 -21.604374 5.0 463 0.273246 False REGULAR USD 2025-12-19
820 AAPL251219C00280000 2023-08-04 19:59:11+00:00 280.0 6.90 6.75 7.20 -2.249999 -24.590160 168.0 1234 0.269752 False REGULAR USD 2025-12-19
821 AAPL251219C00290000 2023-08-04 19:57:55+00:00 290.0 5.85 5.45 5.85 -1.650000 -22.000002 11.0 588 0.264854 False REGULAR USD 2025-12-19
822 AAPL251219C00300000 2023-08-04 19:54:37+00:00 300.0 4.75 4.60 4.80 -1.350000 -22.131147 385.0 4941 0.261482 False REGULAR USD 2025-12-19
823 AAPL251219C00310000 2023-08-04 19:57:48+00:00 310.0 3.82 3.70 3.85 -1.280000 -25.098038 162.0 3304 0.257118 False REGULAR USD 2025-12-19

824 rows × 15 columns

In [4]:
yoyo = pd.DataFrame({'strike': options_data.strike, 'impliedVolatility': options_data.impliedVolatility, 'ExpirationDate': options_data.ExpirationDate})
In [5]:
import plotly.express as px

fig = px.scatter_3d(yoyo, x='strike', y='ExpirationDate', z='impliedVolatility',
              color='impliedVolatility')

# Customize the layout
fig.update_layout(
    title='3D Scatter Plot of Implied Volatility',
    scene=dict(
        xaxis_title='Strike',
        yaxis_title='Expiration Date',
        zaxis_title='Implied Volatility'
    ), width=1000, height=900,
    margin=dict(l=0, r=0, b=0, t=40),  # Adjust margins if needed
    # Add more layout customizations here
)


fig.show()

Esempio di come la volatilità implicita è correlata con il prezzo delle opzioni

In [6]:
symbol = "AAPL"
ticker = yf.Ticker(symbol)
ticker.options[6]
Out[6]:
'2023-09-22'
In [7]:
exp_date = ticker.options[6]
options_chain = ticker.option_chain(exp_date)
calls = options_chain.calls
In [8]:
import pandas as pd
df= pd.DataFrame({'strike':calls.strike, 'impliedVolatility': calls.impliedVolatility, 'lastPrice': calls.lastPrice})
df
Out[8]:
strike impliedVolatility lastPrice
0 130.0 0.608158 53.31
1 150.0 0.462530 36.41
2 155.0 0.440435 29.77
3 160.0 0.398199 26.50
4 165.0 0.349250 19.52
5 170.0 0.310432 15.10
6 175.0 0.275642 11.15
7 180.0 0.256233 7.60
8 185.0 0.238899 4.90
9 190.0 0.227486 2.91
10 195.0 0.229622 1.62
11 200.0 0.219734 0.86
12 205.0 0.222176 0.47
13 210.0 0.229012 0.27
14 215.0 0.241707 0.17
15 220.0 0.255867 0.13
16 225.0 0.271492 0.10
17 230.0 0.287117 0.08
18 235.0 0.299812 0.06
19 240.0 0.320319 0.05
20 245.0 0.334968 0.04
21 255.0 0.365241 0.03
22 265.0 0.402350 0.02
In [9]:
import matplotlib.pyplot as plt
%matplotlib inline

fig, ax1 = plt.subplots(figsize=(18, 8), dpi=100)


ax1.set_ylabel('Option Price', color="black")
ax1.plot(df.lastPrice, color="black")
ax1.tick_params(axis='y', labelcolor="black")

ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis

ax2.set_ylabel('Implied Volatility', color="black")  # we already handled the x-label with ax1
ax2.plot(df.impliedVolatility, color="blue")
ax2.tick_params(axis='y', labelcolor="black")

fig.tight_layout()  # otherwise, the right y-label is slightly clipped
plt.show()
In [10]:
s0 = yf.download(symbol, period="max", interval="1d")["Close"]
S = s0[-1]
S
[*********************100%***********************]  1 of 1 completed
Out[10]:
181.99000549316406
In [ ]: